package cn.edu.nju.newsFeed;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cn.edu.nju.R;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.style.CharacterStyle;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * This class is used to help format comment list item and news feed list item
 * @author JiajunYao
 *
 */
public class ListItemFormatHelper {
	private Activity context;
	private List<String> emotions;
	private ForegroundColorSpan defaultNameSpan;
	private ForegroundColorSpan defaultContentSpan;
	private ForegroundColorSpan defaultCommentSpan;
	private ForegroundColorSpan defaultLikeSpan;
	private ImageSpan imageSpan;
	
	public ListItemFormatHelper(Activity context){
		this.context = context;
		
		defaultNameSpan = new ForegroundColorSpan(context.getResources().getColor(R.color.blue));
		defaultContentSpan = new ForegroundColorSpan(context.getResources().getColor(R.color.black));
		defaultCommentSpan = new ForegroundColorSpan(context.getResources().getColor(R.color.gray));
		defaultLikeSpan = new ForegroundColorSpan(context.getResources().getColor(R.color.gray));
		
		try {
			emotions = Arrays.asList(context.getAssets().list("emotion"));
		} catch (IOException e) {
			emotions = new ArrayList<String>();
		}
	}
	
	public void setAvatar(ImageView view, FeedItem item){
		if(item.getAvatar() == null){
			view.setBackgroundResource(R.drawable.ic_default_avatar);
		} else{
			view.setBackgroundDrawable(new BitmapDrawable(item.getAvatar()));
		}
	}
	
	public void setContentText(TextView view, FeedItem item, CharacterStyle nameSpan, CharacterStyle contentSpan){
		if(nameSpan == null){
			nameSpan = defaultNameSpan;
		}
		if(contentSpan == null){
			contentSpan = defaultContentSpan;
		}
		
		String text = item.getPostUserName() + "  " + item.getPostContent();
		view.setText(text);
		Spannable spans = (Spannable)view.getText();
		spans.setSpan(nameSpan, 0, item.getPostUserName().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		
		// convert emotion string to emotion image
		int startIndex = item.getPostUserName().length() + 2;
		String emotionName;
		Pattern emotionPattern = Pattern.compile("\\[.+?\\]");
		Matcher emotionMatcher = emotionPattern.matcher(text);
		boolean matchResult = emotionMatcher.find();
		while(matchResult){
			// avoid user name has '[**]'
			if(emotionMatcher.start() >= startIndex){
				if(startIndex < emotionMatcher.start()){
					spans.setSpan(CharacterStyle.wrap(contentSpan), startIndex, emotionMatcher.start(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
				}
				// avoid empty '[]'
				if(emotionMatcher.end() - emotionMatcher.start() > 2){ 
					emotionName = text.substring(emotionMatcher.start() + 1, emotionMatcher.end() - 1);
					if(emotionExist(emotionName)){
						Drawable emotionDrawable;
						try {
							emotionDrawable = Drawable.createFromStream(context.getAssets().open("emotion/" + emotionName + ".png"), null);
							emotionDrawable.setBounds(0, 0, 33, 33);
							imageSpan = new ImageSpan(emotionDrawable, ImageSpan.ALIGN_BASELINE);
							spans.setSpan(imageSpan, emotionMatcher.start(), emotionMatcher.end(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
						} catch (IOException e) {
							spans.setSpan(CharacterStyle.wrap(contentSpan), emotionMatcher.start(), emotionMatcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
						}										
					}
					else{
						spans.setSpan(CharacterStyle.wrap(contentSpan), emotionMatcher.start(), emotionMatcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
					}
				}
				else{
					spans.setSpan(CharacterStyle.wrap(contentSpan), emotionMatcher.start(), emotionMatcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
				}
				startIndex = emotionMatcher.end();			
			}
			matchResult = emotionMatcher.find();
		}
		
		// if there are remaining text
		if(startIndex < text.length()){
			spans.setSpan(contentSpan, startIndex, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		}
	}
	
	public void setTimeText(TextView view, FeedItem item){
		view.setText(item.getPostTime());
	}
	
	public void setCommentNumberText(TextView view, NewsFeedItem item, CharacterStyle commentSpan){
		if(commentSpan == null){
			commentSpan = defaultCommentSpan;
		}
		String text = "" + item.getCommentsNumber() + context.getResources().getString(R.string.comment);
		view.setText(text);
		Spannable spans = (Spannable)view.getText();
		spans.setSpan(commentSpan, 0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
	}
	
	public void setLikeNumberText(TextView view, FeedItem item, CharacterStyle likeSpan){
		if(likeSpan == null){
			likeSpan = defaultLikeSpan;
		}
		String text = "" + item.getLikeNumber() + context.getResources().getString(R.string.like);
		view.setText(text);
		Spannable spans = (Spannable)view.getText();
		spans.setSpan(likeSpan, 0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
	}
	
	// the image view should set the tag R.id.VIEW_POSITION_TAG
	public void setPreviewImage(ImageView view, NewsFeedItem item, boolean clickable){
		// this imageview may be reused by android system
		view.setImageBitmap(null);
		Bitmap image = item.getPreviewImage();
		if(image != null){
			view.setImageBitmap(image);
			if(clickable){
				view.setOnClickListener(new OnClickListener() {				
					public void onClick(View imageView) {
						int position = (Integer) imageView.getTag(R.id.VIEW_POSITION_TAG);
						Intent intent = new Intent(context, ImageViewActivity.class);
						intent.putExtra(NewsFeedActivity.FEED_ITEM_POSITION, position);
						context.startActivity(intent);
					}
				});
			}
		}
	}
	
	// determine whether an emotion image exists
	private boolean emotionExist(String emotionName){
		return emotions.contains(emotionName + ".png");
	}
}
